home *** CD-ROM | disk | FTP | other *** search
- /*
- Copyright © 1994 Mikhail Fridberg.
- This is my implementation of BSD socket library for MacTCP.
- It supports only limited number of socket calls
- */
-
-
- #include <MacTCPCommonTypes.h>
- #include <AddressXlation.h>
- #include <TCPPB.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <time.h>
- #include <stddef.h>
- #include <string.h>
- #include "tcplow.h"
- #include "MacSocket.h"
-
-
-
- void bzero(void *s, long size)
- {
- memset(s, 0L, size);
- }
-
- /* Socket() */
-
-
- long socket(long af, long type, long protocol)
- {
- OSErr err;
- u_long stream;
- u_long recvLen;
- long s = 0L;
- Ptr recvPtr = 0;
-
- /* check for valid arguments, only TCP calls supported and only for
- Internet style addreses
- */
-
- if (af != AF_INET) {
- errno = EAFNOSUPPORT;
- return -1;
- }
- if (type != SOCK_STREAM) {
- errno = ESOCKTNOSUPPORT;
- return -1;
- }
- if (protocol != 0L) {
- errno = EPROTONOSUPPORT;
- return -1;
- }
-
- /* Make buffer for the data */
-
- recvLen = BUFF_SIZE;
- recvPtr = malloc(recvLen);
-
- /* create a socket */
-
- if ((err = MemError())==noErr) {
- err = LowTCPCreateStream(&stream,recvPtr,recvLen,(TCPNotifyProc)nil);
- } else
- {
- errno = ENOBUFS;
- return -1;
- }
-
- /* check results */
-
- if (err == noErr) {
- errno = 0L;
- return stream;
- } else
- if (err == invalidLength) {
- errno = ENOBUFS;
- return -1;
- } else
- if (err == insufficientResources) {
- errno = EMFILE;
- return -1;
- } else
- {
- errno = err;
- return -1;
- }
-
- }
-
-
- /* Connect () */
-
- long connect (long s, struct sockaddr *name, long namelen)
- {
- OSErr err;
- long stream = 0L;
- tcp_port kPort;
- ip_addr ipAdress;
- byte kTimeOut = 0x20;
- ip_addr localHost = 0;
- tcp_port localPort = 0;
-
- stream = s;
- BlockMove(&name->sa_data[0],&kPort,sizeof(short));
- BlockMove(&name->sa_data[2],&ipAdress,sizeof(long));
-
- err = LowTCPOpenConnection((StreamPtr)stream, kTimeOut, ipAdress, kPort, &localHost, &localPort);
-
-
- if (err == noErr) return 0L;
-
- if (err == streamAlreadyOpen) {
- errno = EISCONN;
- return -1;
- } else
- if (err == invalidStreamPtr) {
- errno = EBADF;
- return -1;
- } else
- if (err == commandTimeout) {
- errno = ETIMEDOUT;
- return -1;
- } else {
- errno = err;
- return -1;
- }
- }
-
- /* gethostbyname() */
-
- struct hostent *gethostbyname (char *name)
- {
- OSErr err;
- u_long addr,namelength;
- static struct hostent *myHost = 0L;
- static struct hostInfo hInfo;
- Boolean done=false;
- long len;
- static char *addrPtr = (char *)&hInfo.addr[0];
-
- if (myHost == 0L)
- myHost = (struct hostent *)malloc(sizeof(*myHost));
-
- if (myHost == 0L) printf( "Could not create host entry, Error = %d\n",MemError());
-
- if ((err = OpenResolver(nil)) != noErr) return NULL;
- err = StrToAddr(name, &hInfo, DNRResultProc, (char*)&done);
- if (err == cacheFault) {
- while (!done) GiveTime();
- err = hInfo.rtnCode;
- }
-
- if ((err == nameSyntaxErr) || (err == noNameServer) || (err == authNameErr) ||
- (err == noAnsErr) || (err == dnrErr) || (err == outOfMemory) ||
- (err == notOpenErr)) {
- free(myHost);
- myHost = 0L;
- CloseResolver();
- return myHost;
- }
-
- CloseResolver();
- myHost->h_name = hInfo.cname;
- myHost->h_length = 4;
- myHost->h_addrtype = 2;
- myHost->h_addr_list = &addrPtr;
- return (myHost);
- }
-
- /*recv ()*/
-
- long recv (long s, char *buf, long len, long flags)
- {
-
- Boolean retry = false;
- OSErr err;
- u_short tempLen;
-
- tempLen = len;
- if ((err = RecvData (s, buf, &tempLen, retry)) == noErr) return (long)tempLen;
- errno = err;
- return -1;
- }
-
-
- /* send() */
-
- long send (long s, char *msg, long len, long flags)
- {
- OSErr err;
-
-
- if ((err = SendData (s, msg, (u_short)len)) == noErr) return (long)len;
- errno = err;
- return -1;
- }
-
-
- /* shutdown() */
-
- long shutdown (long s, long how)
- {
- OSErr err;
- switch (how) {
- case 0L:
- err = LowTCPClose(s, 0x20);
- if (err != noErr && err != connectionDoesntExist &&
- err != connectionClosing && err != connectionTerminated) {
- LowTCPAbort(s);
- return err;
- }
-
- break;
- case 1:
- err = LowTCPClose(s, 0x20);
- if (err != noErr && err != connectionDoesntExist &&
- err != connectionClosing && err != connectionTerminated) {
- LowTCPAbort(s);
- return err;
- }
- break;
- case 2:
- return LowTCPAbort(s);
- break;
-
- }
-
- }
-
-
- /* close() */
-
- long socket_close (long s)
- {
- OSErr err;
- Ptr recvPtr = 0L;
- unsigned long recvLen;
-
- if ((err = LowTCPRelease(s,&recvPtr,&recvLen)) == noErr) free(recvPtr);
- if (MemError() != noErr) printf("Could not free memory, Error = %d\n", MemError());
- return err;
-
- }
-
- /* getserverbyname() */
- struct servent *getservbyname(char *name, char *proto)
- {
- static struct servent *servInfo = 0L;
-
- servInfo = (struct servent *)malloc(sizeof(*servInfo));
-
- if (servInfo == 0L) printf("Could not allocate memory for server entry, Error= %d\n", MemError());
-
- servInfo->s_port= 8000;
- servInfo->s_proto = name;
- return (servInfo);
- }
-
- /* All following calls are not imlemented and commented out. I found that I never
- needed them, so I dfesided not to bother*/
-
-
- unsigned short htons(unsigned short hostshort)
- {
- /* It is probably not needed, so nothing here*/
- }
-
-
-
-
- /*
- * s_select(nfds, readfds, writefds, exceptfds, timeout)
- *
- * select() examines the I/O descriptor sets whose addresses
- * are passed in readfds, writefds, and exceptfds to see if
- * some of their descriptors are ready for reading, ready for
- * writing, or have an exceptional condition pending. width is
- * the number of bits to be checked in each bit mask that
- * represent a file descriptor; the descriptors from 0 through
- * width-1 in the descriptor sets are examined. Typically
- * width has the value returned by getdtablesize for the
- * maximum number of file descriptors. On return, select
- * replaces the given descriptor sets with subsets consisting
- * of those descriptors that are ready for the requested opera-
- * tion. The total number of ready descriptors in all the sets
- * is returned.
- *
- * If timeout is not a NULL pointer, it specifies a maximum
- * interval to wait for the selection to complete. If timeout
- * is a NULL pointer, the select blocks indefinitely. To
- * effect a poll, the timeout argument should be a non-NULL
- * pointer, pointing to a zero-valued timeval structure.
- *
- * Any of readfds, writefds, and exceptfds may be given as NULL
- * pointers if no descriptors are of interest.
- *
- * Using select to open a socket for reading is analogous to
- * performing an accept call.
- *
- * select() returns the number of ready descriptors that are
- * contained in the descriptor sets, or -1 if an error
- * occurred. If the time limit expires then select() returns
- * 0. If select() returns with an error the descriptor sets
- * will be unmodified.
- */
- /*
- int s_select( long nfds, long *readfds, long *writefds,
- long *exceptfds, struct timeval *timeout)
- {
- long count = 0;
-
- while (count < nfds || !timeout) {
- check_reads(readfds, count);
- check_writes(writefds, count);
- check_except(exceptfds, count);
- count++;
-
-
- }
-
-
- }
-
- check_reads (long *readfds, long count)
- {
-
-
- }
-
-
- check_writes (long *readfds, long count)
- {
-
-
- }
-
- check_except (long *readfds, long count)
- {
-
-
- }
-
- */